//
//  Copyright 2012 Christopher Dudley
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
#ifndef _CONFIG_H_
#define _CONFIG_H_

/*
 *  This header defines macros representing features present in the compiler.
 *  At the moment, this is mostly used to determine C++11 support.
 *
 *  In the future, this file could be generated by the compilation script after
 *  tests are run on the compiler to determine its feature set.
 */

// Check if we have C++11 support

#if __cplusplus >= 201103L
    #ifndef _HAS_CPP_11
        #define _HAS_CPP_11
    #endif
#endif

// C++11 features
//
// All of the options are surrounded by ifndef checks so that external checks
// for the presence of C++11 options can be used to override this.
#ifdef _HAS_CPP_11
    #ifndef _HAS_STD_HASH
        #define _HAS_STD_HASH
    #endif

    #ifndef _HAS_DECLTYPE
        #define _HAS_DECLTYPE
    #endif

    #ifndef _HAS_AUTO
        #define _HAS_AUTO
    #endif

    // libstdc++ specific check.
    // If _GLIBCXX_USE_NANOSLEEP is not defined, this_thread::sleep_for and
    // this_thread::sleep_until are not declared in <thread>, even though they
    // are required by the C++11 Standard. If libstdc++ is configured with the
    // flag --enable-libstdcxx-time, the configure script will check for the
    // existence of the nanosleep function and, if found, define this macro.
    // However, most distributions don't seem to configure libstc++ with this
    // option, so the macro is almost never defined. This only changes things
    // in the header, so defining it yourself on a system that has nanosleep
    // will work, but is an extremely ugly and non-portable hack.
    //
    // For more information, see this post on StackOverflow:
    // http://stackoverflow.com/questions/12523122/what-is-glibcxx-use-nanosleep-all-about

    #ifndef _HAS_SLEEP_FOR
        #ifdef _GLIBCXX_USE_NANOSLEEP
            #define _HAS_SLEEP_FOR
        #endif // _GLIBCXX_USE_NANOSLEEP
    #endif // _HAS_SLEEP_FOR

    #ifndef _HAS_SLEEP_UNTIL
        #ifdef _GLIBCXX_USE_NANOSLEEP
            #define _HAS_SLEEP_UNTIL
        #endif // _GLIBCXX_USE_NANOSLEEP
    #endif // _HAS_SLEEP_UNTIL

    #ifndef _HAS_STD_RANDOM
        #define _HAS_STD_RANDOM
    #endif // _HAS_STD_RANDOM

#endif//_HAS_CPP_11

#ifdef _HAS_THREAD_LOCAL
    #define THREAD_LOCAL thread_local
#else
    // Use __thread and hope it works.
    #define THREAD_LOCAL __thread
#endif // _HAS_THREAD_LOCAL

#endif//_CONFIG_H_
